package com.zimmur.app.mocolink.background.aop;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSON;
import com.zimmur.app.mocolink.background.common.ReturnJsonEntity;
import com.zimmur.app.mocolink.background.common.StatusCodeEnum;
import com.zimmur.app.mocolink.background.util.PublicKeyUtil;
import com.zimmur.app.mocolink.background.util.SecretUtil;
import com.zimmur.app.mocolink.domain.util.MD5;

public class RequestHeadersInterceptor extends HandlerInterceptorAdapter {
	private Logger log = LoggerFactory.getLogger(RequestHeadersInterceptor.class);
	@Autowired
	private PublicKeyUtil publicKeyUtil;
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=UTF-8"); 		
		ReturnJsonEntity entity = new ReturnJsonEntity(StatusCodeEnum.CODE100404);
		log.debug(request.getContentLength()+""); 		
		//验证时间戳
        String timestamp = request.getHeader("timestamp");
        String bodyLength=request.getHeader("body_length");
        String userSign = request.getHeader("sign");
        String token = request.getHeader("token");
        if(StringUtils.isEmpty(timestamp)){        	
        	response.getWriter().write(JSON.toJSONString(entity));
        	return false;
        }
        try {
        	long requestTime = Long.parseLong(timestamp);
	        long curTime = System.currentTimeMillis();
	        long outTime=10 * 60 * 1000;//10分钟毫秒数
	        if((curTime - requestTime) > outTime){
	        	entity = new ReturnJsonEntity(StatusCodeEnum.CODE100402);
	        	response.getWriter().write(JSON.toJSONString(entity));
	            return false;
	        }
		} catch (Exception e) {
			log.error(e.getMessage());
			entity = new ReturnJsonEntity(StatusCodeEnum.CODE100000);
			response.getWriter().write(JSON.toJSONString(entity));
			return false;
		}
        //验证签名数据
		if(StringUtils.isEmpty(userSign) || StringUtils.isEmpty(token) ){
			response.getWriter().write(JSON.toJSONString(entity));
			return false;
		}
		
		if(!checkAuthor(timestamp, request.getRequestURI(), request.getMethod(),bodyLength, userSign,token)){
			entity = new ReturnJsonEntity(StatusCodeEnum.CODE100401);
			response.getWriter().write(JSON.toJSONString(entity));
			return false;
		}
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception ex) throws Exception {
	}
	/**
	 * 访问身份验证
	 * @param request 请求方法(GET/POST)
	 * @param sign 请求签名
	 * @param token 用户授权码
	 * @param key  公钥
	 * @return true = 验证通过 false=验证失败
	 */
	private  boolean checkAuthor(String timestamp,String uri,String method,String bodyLength,String sign,String token){
		try {
			Integer userId = SecretUtil.Instance().getUserId(token);
			
			//加密方法: httpMethod + apiUri + timestamp +token+publickey+body数据长度
			String publicKey = publicKeyUtil.getKey();
			String content =method+uri+timestamp+token+publicKey+bodyLength;
			String signMd5 = MD5.MD5Encode(content).toUpperCase();
			String checkSign=userId+":"+signMd5;
			log.debug("签名内容："+content+",加密结果："+checkSign);
			if(checkSign.equals(sign)){
				return true;
			}
		} catch (Exception e) {
			log.error(e.getMessage(),e);
		}
		return false;
	}
	
}
